<script lang="ts" setup>
import * as L from 'leaflet';
import { ref, onMounted, onUnmounted } from 'vue';
import "leaflet/dist/leaflet.css";
import 'leaflet.chinatmsproviders';
import 'proj4leaflet';
import 'proj4';
import List from './List.vue';
import * as signalR from '@microsoft/signalr';
import { ElNotification } from 'element-plus';
// import _ from 'lodash'; // 导入 lodash
import { format } from 'date-fns'; // 导入日期格式化函数

const MapKey = "c821b8bede8a0e999e88ac75e39a7898";
let map: L.Map;
const sessionId = ref<string | null>(null); // 存储 sessionId
const sessionId2 = ref<string | null>(null); // 存储 sessionId
const elementNames = ref<{ id: string, name: string }[]>([]);
const ruleDataTemp = ref<{}[]>([]);
const polygons = ref<{ [key: string]: L.Polygon }>({});
const assignedCounts = ref<{ [key: string]: number }>({}); // 存储分配人数
const lowBatteryDevices = ref<Set<string>>(new Set());
const lowBatteryCount = ref(0);
const onlineCount = ref(0); // 定义在线人数的状态
const gridData = ref<{ name: string; time: string }[]>([]);

// 获取当天的 0 点时间
function getStartOfDay(): string {
  const now = new Date();
  now.setHours(0, 0, 0, 0);
  return format(now, 'yyyy-MM-dd HH:mm:ss');
}

// 获取当前时间
function getCurrentTime(): string {
  return format(new Date(), 'yyyy-MM-dd HH:mm:ss');
}

const staffIcon = L.icon({
  iconUrl: '/staff.png',
  iconSize: [32, 32],
});

// SignalR 连接实例
let connection: signalR.HubConnection;
let updateTimer: number;

// 定义一个画多边形的函数
async function fetchRegionPoints(regionId: string) {
  try {
    const response = await fetch(`http://47.100.168.221:9999/gps-web/api/get_region_points.jsp?sessionId=${sessionId.value}&id=${regionId}`);
    const data = await response.json();
    if (data && data.entity && data.entity.points) {
      return data.entity.points.split(";").map((point: string) => {
        const [lng, lat] = point.split(",");
        return [parseFloat(lat), parseFloat(lng)] as [number, number];
      });
    }
    // 如果数据不完整或不存在，返回 null
    return null;
  } catch (error) {
    console.error("Error fetching region points:", error);
    return null;
  }
}

// 获取数据
async function fetchData() {
  // 登录接口 SHJC_PDGJ 获取动态 sessionId
  const login1 = await fetch(`http://47.100.168.221:9999/gps-web/api/login.jsp?password=c65c636e668a7872e393058856be20f5&userId=SHJC_PDGJ&loginType=user`);
  const loginData1 = await login1.json();
  sessionId.value = loginData1.sessionId;

  // 登录接口 user_shjt 获取动态 sessionId
  const login2 = await fetch(`http://47.100.168.221:9999/gps-web/api/login.jsp?password=e10adc3949ba59abbe56e057f20f883e&userId=user_shjt&loginType=user`);
  const loginData2 = await login2.json();
  sessionId2.value = loginData2.sessionId;

  // 获取区域数据【获取权限下所有区域(不含经纬度)】
  const regionsResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_regions.jsp?sessionId=${sessionId.value}&type=1`);
  const regionsData = await regionsResponse.json();
  if (regionsData && regionsData.data) {
    elementNames.value = regionsData.data.map((element: any) => ({
      id: element.id,
      name: element.name
    }));

    // 获取规则数据【获取权限下指定某类别规则】
    const ruleResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_rules.jsp?sessionId=${sessionId2.value}&ruleType=3`);
    const ruleData = await ruleResponse.json();
    if (ruleData && ruleData.data) {
      for (const item of ruleData.data) {
        // 【获取权限下规则分配记录】
        const ruleListResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_rule_assign.jsp?sessionId=${sessionId2.value}&type=rule&resId=${item.id}`);
        const ruleListData = await ruleListResponse.json();
        if (ruleListData.list && ruleListData.list.length > 5) {
          ruleDataTemp.value.push(item.regionId);
        }
        assignedCounts.value[item.regionId] = ruleListData.list.length;
      }
    }
  } else {
    console.error("Error fetching or processing regions data.");
  }
  
  // 获取在线人数【车辆统计数据(按状态)】
  const response = await fetch(`http://47.100.168.221:9999/gps-web/api/get_car_count.jsp?sessionId=${sessionId.value}`);
  const data = await response.json();
  if (data) {
    onlineCount.value = data.online;
  } else {
    console.error("Invalid data format or response code");
  }

  try {
    // 获取 carIds 列表【车辆明细列表】
    const carListResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_car_list.jsp?sessionId=${sessionId.value}`);
    const carListData = await carListResponse.json();

    if (carListData && carListData.list) {
      const carIds = carListData.list.map((car: any) => car.carId).join(',');

      // 获取当天0点时间和当前时间
      const startTime = getStartOfDay();
      const endTime = getCurrentTime();

      // 调用【历史报警统计】获取低电量数据
      const alarmResponse = await fetch(`http://47.100.168.221:9999/gps-web/api/get_alarm_h_pfm_count.jsp?sessionId=${sessionId.value}&carIds=${carIds}&startTime=${startTime}&endTime=${endTime}`);
      const alarmData = await alarmResponse.json();

      if (alarmData && alarmData.list) {
        // 清空当前 gridData 以确保不会重复记录
        gridData.value = [];

        alarmData.list.forEach((car: any) => {
          car.list.forEach((alarm: any) => {
            if (alarm.typeId === 'p1') {
              gridData.value.push({
                name: car.plate,
                time: getCurrentTime(), // 设置为当前时间
              });
            }
          });
        });

        lowBatteryCount.value = gridData.value.length; // 更新低电量设备数量
      }
    }
  } catch (error) {
    console.error("Error fetching alarm data:", error);
  }

}

// 初始化地图
function initializeMap() {
  const imgm = L.tileLayer.chinaProvider('TianDiTu.Satellite.Map', {
    maxZoom: 18,
    minZoom: 8,
    key: MapKey
  });
  const imga = L.tileLayer.chinaProvider('TianDiTu.Satellite.Annotion', {
    maxZoom: 18,
    minZoom: 8,
    key: MapKey
  });

  const image = L.layerGroup([imgm, imga]);
  const baseLayers = {
    "影像": image,
  };
  const overlayLayers = {
    "影像": image,
  };

  map = L.map("map", {
    center: [31.144339395192617, 121.80826876009174],
    zoom: 14,
    maxZoom: 18,
    minZoom: 8,
    layers: [image],
    zoomControl: false, // 不显示左上角的缩放控件
  });

  L.control.layers(baseLayers, overlayLayers).addTo(map);

  let attribution = map.attributionControl;
  attribution.setPrefix('<span><img class="relative top-[2.3px] pt-[2px]" height=17 src="/JTlogo.ico"> 上海疆通科技</span>');
  L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '数据引自 <a href="https://www.tianditu.gov.cn">&copy; 天地图</a>'
  }).addTo(map);

  // 画电子围栏和开启围栏
  elementNames.value.forEach(async (element: any) => {
    const coordinates = await fetchRegionPoints(element.id);
    if (coordinates) {
      const polygon = L.polygon([coordinates], {
        color: ruleDataTemp.value.includes(element.id) ? 'green' : '#a0522d',
        fillColor: ruleDataTemp.value.includes(element.id) ? 'green' : 'none',
        fillOpacity: ruleDataTemp.value.includes(element.id) ? 0.5 : 0.15
      }).addTo(map);
      polygons.value[element.id] = polygon; // 保存多边形对象
      polygon.bindPopup(element.name);
      polygon.on('click', function () {
        polygon.bringToFront();
      });
    }
  });
}

await fetchData();

// 使用节流函数来限制 fetchData 的调用频率
// const throttledFetchData = _.throttle(fetchData, 5000); // 每5秒最多调用一次

// 缓存标记位置
const markerCache = new Map<string, L.Marker>();

const updateMarkerPosition = (carId: string, lat: number, lng: number, carName: string, alarmTime:string, isLowBattery: boolean = false) => {
  window.requestAnimationFrame(() => {
    let marker = markerCache.get(carId);

    if (marker) {
      marker.setLatLng([lat, lng]);
    } else {
      marker = L.marker([lat, lng], {
        icon: staffIcon,
      }).addTo(map).bindPopup(carName);

      marker.setZIndexOffset(99);
      markerCache.set(carId, marker);
    }
    
    // 如果是低电量状态，更新弹出内容
    if (isLowBattery) {
      marker.setPopupContent(`${carName}<br>低电量警告<br>${alarmTime}`);
    }

    // 每次点击图标时，检查低电量状态
    marker.on('click', () => {
      if (lowBatteryDevices.value.has(carId)) {
        marker.setPopupContent(`${carName}<br>低电量警告<br>${alarmTime}`);
      }
      marker.openPopup();
    });
  });
};

onMounted(async () => {
  initializeMap();

  updateTimer = window.setInterval(async () => {
    await fetchData();
  }, 2000);

  // // 使用节流后的函数来更新数据
  // updateTimer = window.setInterval(async () => {
  //   await throttledFetchData();
  // }, 2000);

  // 创建 SignalR 连接
  connection = new signalR.HubConnectionBuilder()
    .withUrl("http://47.100.168.221:8080/location")
    .withAutomaticReconnect()
    .build();

  // 启动连接
  connection.start()
    .then(() => console.log("SignalR connected."))
    .catch((err: any) => console.error("Error connecting to SignalR:", err));
  
  // 处理定位数据
  connection.on("OrientationMessage", (positionData: any) => {
    
    positionData = JSON.parse(positionData);
    console.log("Received positionData:", positionData);

    const { carId, lat, lng, carName } = positionData;
    updateMarkerPosition(carId, lat, lng, carName);
  });

  // 处理报警数据
  connection.on("AlarmMessage", async (alarmData: any) => {
    const alarmData1 = JSON.parse(alarmData);
    console.log("%c Line:210 🍧 alarmData", "color:#e41a6a", alarmData);

    const { alarmName, carId, carName, alarmTime, typeId, addr } = alarmData1;
    
    if (typeId === 'r4' && addr?.includes("浦东")) {
      ElNotification({
        title: alarmName,
        message: `${carName}<br>${alarmTime}`,
        type: 'warning',
        position: 'top-right',
        duration: 60000,
        offset: 56, // 设置偏移量，使通知在 Header 下面显示
        dangerouslyUseHTMLString: true, // 允许使用 HTML 片段
      });
    }

    // 低电量弹窗+计算总数
    if (typeId === 'p1' || typeId === 'p2' && addr?.includes("浦东")) {
      const marker = markerCache.get(carId);
      if (marker) {
        marker.setPopupContent(`${carName}<br>低电量警告<br>${alarmTime}`);
        marker.openPopup();
      }
      // if (!lowBatteryDevices.value.has(carId)){
      //   lowBatteryDevices.value.add(carId);
      //   lowBatteryCount.value += 1;

      //   // 添加设备信息到 gridData
      //   gridData.value.push({ name: carName, time: alarmTime });
      // }

      // 更新标记位置并保存低电量状态
      updateMarkerPosition(carId, marker?.getLatLng().lat ?? 0, marker?.getLatLng().lng ?? 0, carName, alarmTime, true);
    }
  });

  // 下线人员在地图上移除图片
  connection.on("OnlineMessage", (onlineData: any) => {
    onlineData = JSON.parse(onlineData);
    console.log("Received onlineData:", onlineData);

    const { carId, isOnline } = onlineData;

    if (isOnline === 'false') {
      if (markerCache.has(carId)) {
        const marker = markerCache.get(carId);
        map.removeLayer(marker);
        markerCache.delete(carId);
        // 如果设备下线且在低电量列表中，将其移除并减少计数
        if (lowBatteryDevices.value.has(carId)) {
          lowBatteryDevices.value.delete(carId);
          lowBatteryCount.value -= 1;

          // 从 gridData 中删除相应的数据
          gridData.value = gridData.value.filter(device => device.name !== carId);
        }
      }
    }
  });
});

onUnmounted(() => {
  connection && connection.stop(); // 停止 SignalR 连接
  map && map.remove();
  if (updateTimer) {
    window.clearInterval(updateTimer); // 清理定时器
  }
});

const toggleRegion = (regionId: string, isSelected: boolean) => {
  if (polygons.value[regionId]) {
    if (isSelected) {
      polygons.value[regionId].addTo(map);
    } else {
      map.removeLayer(polygons.value[regionId]);
    }
  }
};
</script>

<template>
  <div class="flex h-screen">
    <List :elementNames="elementNames" :ruleData="ruleDataTemp" :assignedCounts="assignedCounts" @toggleRegion="toggleRegion" />
    <div id="map" class="flex-1 h-full"></div>
    <!-- 在线人数看板 -->
    <div class="absolute w-[150px] h-[60px] mt-[10px] left-[19.5vw] bg-[rgb(44,120,191)] p-[10px] rounded shadow-md z-500 flex items-center justify-center">
      <div class="text-white text-lg font-bold text-center">
        飞行区内在线人数<span class="text-yellow-400 text-xl">{{ onlineCount }}</span> 人
      </div>
    </div>
    
    <!-- 电子围栏状态看板 -->
    <div class="absolute w-[100px] h-[70px] top-[105px] left-[20.7vw] bg-white p-[10px] rounded shadow-md z-500">
      <div class="text-[15px] mb-2 text-center">电子围栏状态</div>
      <div class="text-[14px] mb-1 text-center"> ✅ 已启用</div>
      <div class="text-[14px] text-center"> ❌ 未启用</div>
    </div>

    <!-- 低电量数看板 -->
    <el-popover 
      placement="right" 
      :width="`350`"
      trigger="click"
    >
      <template #reference>
        <div class="absolute w-[100px] h-[50px] top-[210px] left-[20.7vw] bg-white p-[10px] rounded shadow-md z-500 text-center cursor-pointer">
          <div class="text-[15px] mb-1 text-center">30% 低电量数</div>
          <span class="text-orange-400 text-xl"> {{ lowBatteryCount }} </span>
        </div>
      </template>
      <el-table :data="gridData" class="flex p-10px">
        <el-table-column width="100" prop="name" label="设备姓名" align="center"/>
        <el-table-column width="250" prop="time" label="欠压时间" align="center"/>
      </el-table>
    </el-popover>

  </div>
</template>

<style>
.leaflet-top.leaflet-right {
  display: none; /* 不显示右上角的堆叠控件 */
}
</style>